<template>
  <div class="page-env-detail">
    <!-- 基本信息面板 -->
    <div class="environment-info">
      <h4 class="zl-title f-mt0">基本信息</h4>
      <Spin fix v-if="isLoading"></Spin>
      <div class="environment-info-box" v-else>
        <Row :gutter="10">
          <Col span="8" class="f-nowrap">
            <span class="info-title">环境名称：</span>
            {{environment.environmentName ? environment.environmentName : environment.environmentId}}
          </Col>
          <Col span="7" class="f-nowrap" v-if="environment.secondaryDomain">
            <span class="info-title">域名：</span> {{environment.secondaryDomain}}{{domain | domainDot}}
          </Col>
          <Col span="9">
            <span class="info-title">创建时间：</span> {{environment.createTime}}
          </Col>
          <Col span="8">
            <span class="info-title">容器CPU最小值/最大值(mCpu)：</span>
            <template v-if="environmentInfo.containerDefaultRequestCpu && environmentInfo.containerDefaultCpu">{{environmentInfo.containerDefaultRequestCpu}}/{{environmentInfo.containerDefaultCpu}}</template>
            <template v-else>暂无</template>
          </Col>
          <Col span="16">
            <span class="info-title">容器内存最小值/最大值(Gi)：</span>
            <template v-if="environmentInfo.containerDefaultRequestMemory && environmentInfo.containerDefaultMemory">{{environmentInfo.containerDefaultRequestMemory}}/{{environmentInfo.containerDefaultMemory}}</template>
            <template v-else>暂无</template>
          </Col>
          <Col span="24">
            <span class="info-title">描述：</span> {{environmentInfo.description ? environmentInfo.description : '暂无描述'}}
          </Col>
        </Row>
      </div>
    </div>

    <!-- 服务组列表（分组展示） -->
    <h4 class="zl-title">服务
      <div class="fr">
        <search placeholder="搜索服务/服务组" @change="searchService"></search>
        <Button type="primary" @click="serviceGroupMani" class="button-add" v-if="hasPermission($store, environmentId, 'GROUP_POST_ENV')">
          <Icon type="md-add" />
          <span class="button-name">添加服务组</span>
        </Button>
        <Button type="primary" @click="addModifyService()" class="button-add" v-if="hasPermission($store, environmentId, 'SERVICE_POST_ENV|GROUP')">
          <Icon type="md-add" />
          <span class="button-name">添加服务</span>
        </Button>
      </div>
    </h4>
    <div class="zl-page-loading" v-if="isLoading">
      <Spin class="zl-page-loading" fix></Spin>
    </div>
    <Card class="group-card" v-else>
      <div class="group-box-list" v-if="serviceGroupList.length > 0">
        <div class="group-box" v-for="group in serviceGroupList" :key="group.id">
          <header class="group-head">
            <Row :gutter="8">
              <Col :span="6">
                <Icon type="md-list" />
                <div class="zl-link" @click="groupDetail(group)"> {{group.name}} </div>
              </Col>
              <Col :span="18">
                <div class="fr">
                  <Dropdown placement="bottom-end" class="group-mani">
                    <Icon type="ios-more" class="group-more" />
                    <DropdownMenu slot="list">
                      <DropdownItem v-if="hasPermission($store, environmentId, 'GROUP_PUT_ENV|GROUP')">
                        <div class="button-inner" @click="serviceGroupDelete(group)" >
                          <Icon type="md-trash" /> 删除
                        </div>
                      </DropdownItem>
                      <DropdownItem v-if="hasPermission($store, environmentId, 'GROUP_DELETE_ENV|GROUP')">
                        <div class="button-inner" @click="serviceGroupMani(group)">
                          <Icon type="ios-create-outline" /> 编辑
                        </div>
                      </DropdownItem>
                      <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE_POST_ENV|GROUP')">
                        <div class="button-inner" @click="addModifyService(group.id)">
                          <Icon type="md-add" /> 添加服务
                        </div>
                      </DropdownItem>
                    </DropdownMenu>
                  </Dropdown>
                </div>
              </Col>
            </Row>
          </header>
          <div class="group-body">
            <div class="service-box flex" v-for="service in group.serviceList" v-if="group.serviceList.length > 0" :key="service.id">
              <div class="flex-status">
                <i class="zl-badge" v-if="service.status === 'active'"></i>
                <i class="zl-badge badge-warning" v-else-if="service.status === 'stopped'"></i>
                <i class="zl-badge badge-error" v-else></i>
              </div>
              <div class="flex-name zl-link">
                <span class="service-name" @click="serviceDetail(group, service)">{{service.id}}</span>
                <div class="service-tip" v-if="service.error">
                  <Tooltip :content="service.error" placement="bottom-start">
                    <Icon type="md-help-circle" />
                  </Tooltip>
                </div>
              </div>
              <div class="flex-1 f-nowrap">
                <Tooltip :content="service.image" placement="top">镜像：{{service.image}}</Tooltip>
              </div>
              <div class="flex-1 flex-node">
                <span>pod副本数:</span>
                <Icon type="md-remove" @click="podCount(group, service, -1)" class="icon-mani" v-if="hasPermission($store, environmentId, 'SERVICE_PATCH_ENV|GROUP')" />
                <span>{{service.replicas}}</span>
                <Icon type="md-add" class="icon-mani" @click="podCount(group, service, 1)" v-if="hasPermission($store, environmentId, 'SERVICE_PATCH_ENV|GROUP')" />
              </div>
              <div class="flex-mani">
                <div class="button-inner" v-if="service.canLink">
                  <a :href="service.access.link" target="blank" v-if="service.access"><Icon type="ios-paper-plane" /> 访问</a>
                </div>
                <div class="button-inner" @click="serviceUpdate(group.id, service)" v-if="hasPermission($store, environmentId, 'SERVICE_DELETE_ENV|GROUP') && service.status === 'active'">
                  <Icon type="md-arrow-round-up" /> 升级
                </div>
                <Dropdown class="service-mani" placement="bottom-end" trigger="click">
                  <Icon type="ios-more" class="service-more" />
                  <DropdownMenu slot="list">
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE_DELETE_ENV|GROUP') && service.id != 'mysql' && (service.type !== 'statefulSet' && (service.status == 'active' || service.status == 'inactive' || service.status == 'degrade'))">
                      <div class="button-inner" @click="addModifyService(group.id, service)" >
                        <Icon type="ios-create-outline" /> 编辑
                      </div>
                    </DropdownItem>
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE_DELETE_ENV|GROUP')">
                      <div class="button-inner" @click="addModifyService(group.id, service, true)" >
                        <Icon type="ios-copy" /> 克隆
                      </div>
                    </DropdownItem>
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE_PATCH_ENV|GROUP') && service.type !== 'statefulSet' && (service.status == 'active' || service.status == 'inactive' || service.status == 'degrade')">
                      <div class="button-inner" @click="removeService(group.id, service)" >
                        <Icon type="md-trash" /> 删除
                      </div>
                    </DropdownItem>
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE_PATCH_ENV|GROUP') && service.type !== 'statefulSet' && service.status == 'stopped'">
                      <div class="button-inner" @click="removeService(group.id, service)" >
                        <Icon type="md-trash" /> 删除
                      </div>
                    </DropdownItem>
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE_PATCH_ENV|GROUP') && service.type === 'statefulSet'">
                      <div class="button-inner" @click="removeService(group.id, service)" >
                        <Icon type="md-trash" /> 删除
                      </div>
                    </DropdownItem>
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE|START_POST_ENV|GROUP|SERVICE') && service.type !== 'statefulSet' && service.status == 'stopped'">
                      <div class="button-inner" @click="startService(group.id, service)" >
                      <Icon type="ios-play" />  启用
                    </div>
                    </DropdownItem>
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE|STOP_POST_ENV|GROUP|SERVICE') && service.type !== 'statefulSet' && (service.status == 'active' || service.status == 'inactive' || service.status == 'degrade')">
                      <div class="button-inner" @click="stopService(group.id, service)">
                        <Icon type="ios-square" /> 停止
                      </div>
                    </DropdownItem>
                    <DropdownItem v-if="hasPermission($store, environmentId, 'SERVICE|REBOOT_DELETE_ENV|GROUP|SERVICE') && service.type !== 'statefulSet' && (service.status == 'active' || service.status == 'inactive' || service.status == 'degrade')">
                      <div class="button-inner" @click="ServiceReboot(group.id, service)">
                        <Icon type="md-refresh" /> 重启
                      </div>
                    </DropdownItem>
                  </DropdownMenu>
                </Dropdown>
              </div>
            </div>
            <div class="service-box" v-else>暂无服务</div>
          </div>
        </div>
      </div>
      <div class="no-data" v-else>暂无服务、服务组，请先添加！</div>
    </Card>

    <!-- 监控 -->
    <monitor :environmentId="environmentId" title="环境运行情况"></monitor>

    <!-- 添加服务组 -->
    <service-group-add :visible.sync="groupVisible" :form="serviceGroupForm" @finish="serviceGroupAddFinish"></service-group-add>

    <!-- 新增、编辑服务 -->
    <service-add-modal :visible.sync="serviceAddVisible" :params="serviceParams" @finish="addModifyServiceFinish" @on-add-group="serviceGroupMani"></service-add-modal>

    <!-- 升级弹窗 -->
    <Modal v-model="updateVisible" title="镜像升级" :loading="true" @on-ok="imageUpdateConfirm" >
      <Form :label-width="80" class="image-update-modal" label-position="left">
        <FormItem label="镜像版本">
          <Select v-model="imageForm.imageVersion">
            <Option :value="image.name" v-for="image in imageVersionList" :key="image.name">{{image.name}}</Option>
          </Select>
        </FormItem>
      </Form>
    </Modal>

  </div>
</template>

<script>
  import Monitor from '@/components/monitor'
  import Search from '@/components/search'
  import ServiceGroupAdd from '@/components/add-service-group/add'
  import ServiceAddModal from '@/components/add-service/modal'
  import Fetch from '@/api/request'
  export default {
    name: 'EnvironmentDetail',
    components: {Monitor, Search, ServiceGroupAdd, ServiceAddModal},
    data() {
      return {
        environmentId: '',
        environment: {},
        isLoading: true,
        columns: [{
          title: '服务组名称',
          render: (h, params) => {
            let name = params.row.name ? params.row.name : params.row.environmentId
            return h('span', {
              class: 'zl-link',
              on: {
                click: () => {
                  this.serviceDetail(params.row)
                }
              }
            }, name)
          }
        }, {
          title: '服务数',
          key: 'serviceCount'
        }, {
          title: '容器数',
          key: 'containerCount'
        }, {
          title: '操作',
          render: (h, params) => {
            return h('div', [
              h('Button', {
                props: {
                  type: 'primary',
                  size: 'small'
                },
                style: {
                  marginRight: '5px'
                },
                on: {
                  click: () => {
                    this.serviceDetail(params.row)
                  }
                }
              }, '操作')
            ])
          }
        }],
        serviceGroupList: [],
        environmentInfo: [],
        domain: '',
        groupVisible: false,
        serviceGroupForm: {},
        serviceAddVisible: false,
        serviceParams: {},
        serviceGroupAddObj: {},
        updateVisible: false,
        imageForm: {
          imageVersion: '',
          groupId: '',
          serviceId: ''
        },
        imageVersionList: [],
        dockerHubs: [],
        podModifing: false
      }
    },
    mounted() {
      let vm = this
      vm.$nextTick(function () {
        vm.environmentId = vm.$route.params.environmentId
        vm.getDomain()
        vm.domain = localStorage.getItem('domain')
        vm.init()
      })
    },
    filters: {
      // 域名最前添加.
      domainDot(name) {
        if (name && name.length > 0 && name[0] !== '.') {
          return '.' + name
        } else {
          return name
        }
      }
    },
    methods: {
      // 获取域名
      getDomain() {
        Fetch.get({
          url: '/api/env/getDomain'
        }).then((res) => {
          localStorage.setItem('domain', res.data)
        })
      },
      podCount(group, service, offset) {
        if (service.replicas + offset < 0) {
          this.$Message.info({
            content: '当前服务已不存在副本数!',
            duration: this.DURATION
          })
          return
        }
        if (this.podModifing) {
          return
        }
        this.podModifing = true
        if (service.replicas + offset === 0) {
          this.$Modal.confirm({
            title: '系统提示',
            content: '副本数为0，意味着停止该服务！',
            onOk: () => {
              this.podHandle(group, service, offset)
            }
          })
        } else {
          this.podHandle(group, service, offset)
        }
      },
      podHandle(group, service, offset) {
        Fetch.patch({
          url: '/api/pod/add',
          params: {
            environmentId: this.$route.params.environmentId,
            groupId: group.id,
            serviceId: service.id,
            data: {
              patchType: 'replicas',
              replicas: service.replicas + offset
            }
          },
          done: () => {
            this.podModifing = false
            service.replicas = service.replicas + offset
          }
        }).then((res) => {
          this.$Message.success({
            content: offset > 0 ? '新增容器成功！' : '减少容器成功！',
            duration: this.DURATION
          })
        })
      },
      // 服务组详情
      groupDetail(group) {
        localStorage.setItem('groupName', group.name)
        this.$router.push('/home/environment/' + this.environmentId + '/info/' + group.id)
      },
      // 确定升级镜像
      imageUpdateConfirm() {
        Fetch.patch({
          url: '/api/environments/' + this.$route.params.environmentId + '/groups/' + this.imageForm.groupId + '/services/' + this.imageForm.serviceId,
          params: {
            environmentId: this.$route.params.environmentId,
            groupId: this.imageForm.groupId,
            serviceId: this.imageForm.serviceId,
            image: this.imageForm.image + ':' + this.imageForm.imageVersion,
            patchType: 'image'
          },
          done: () => {
            this.updateVisible = false
          }}).then((res) => {
            this.$Message.success({
              content: '镜像升级成功！',
              duration: this.DURATION
            })
            this.init()
          })
      },
      // 升级镜像弹出弹窗
      serviceUpdate(groupId, service) {
        this.imageForm.serviceId = service.id
        this.imageForm.groupId = groupId
        this.imageForm.image = service.image.split(':')[0]
        Fetch.get({
          url: '/api/harbor/images/' + service.image.split(':')[0] + '/tags?environment=' + this.$route.params.environmentId,
          self: 'catch'
        }).then((res) => {
          if (res && res.code === '0') {
            this.imageVersionList = res.data
            // 获取最新镜像版本
            if (this.imageVersionList.length > 0) {
              this.imageForm.imageVersion = this.imageVersionList[0].name
              this.updateVisible = true
            } else {
              this.$Message.info({
                duration: 5,
                render: (h, params) => {
                  return h('div', [
                    h('span', '镜像库地址错误。'),
                    h('a', {
                      class: 'zl-link',
                      on: {
                        click: () => {
                          this.$Message.destroy()
                          this.$router.push('/home/environment/' + this.environmentId + '/docker')
                        }
                      }
                    }, '前往添加')
                  ])
                }
              })
            }
          } else {
            this.$Message.warning({
              content: res.message,
              duration: this.DURATION
            })
          }
        }).catch((err) => {
          if (err.message.indexOf('<!DOCTYPE html>') !== -1 || err.message.indexOf('404') !== -1) {
            this.$Message.error({
              content: '升级镜像地址错误，请检查确保镜像正确！',
              duration: 3
            })
          } else {
            this.$Message.error(err.message)
          }
        })
      },
      // 重启服务
      ServiceReboot(groupId, service) {
        this.$Modal.confirm({
          title: '系统提示',
          content: '确定重启' + service.id + '服务',
          loading: true,
          onOk: () => {
            Fetch.delete({
              url: '/api/environments/' + this.$route.params.environmentId + '/groups/' + groupId + '/services/' + service.id + '/reboot',
              done: () => {
                this.$Modal.remove()
              }
            }).then((res) => {
              this.$Message.success({
                content: '重启' + service.id + '服务成功！',
                duration: this.DURATION
              })
              this.init()
            })
          }
        })
      },
      // 启用服务
      startService(groupId, service) {
        this.$Modal.confirm({
          title: '系统提示',
          content: '确定启用' + service.id + '服务',
          loading: true,
          onOk: () => {
            Fetch.post({
              url: '/api/environments/' + this.$route.params.environmentId + '/groups/' + groupId + '/services/' + service.id + '/start',
              done: () => {
                this.$Modal.remove()
              }
            }).then((res) => {
              this.$Message.success({
                content: '启用' + service.id + '服务成功！',
                duration: this.DURATION
              })
              this.init()
            })
          }
        })
      },
      // 停止服务
      stopService(groupId, service) {
        this.$Modal.confirm({
          title: '系统提示',
          content: '确定停止' + service.id + '服务',
          loading: true,
          onOk: () => {
            Fetch.post({
              url: '/api/environments/' + this.$route.params.environmentId + '/groups/' + groupId + '/services/' + service.id + '/stop',
              done: () => {
                this.$Modal.remove()
              }
            }).then((res) => {
              this.$Message.success({
                content: '停止' + service.id + '服务成功！',
                duration: this.DURATION
              })
              this.init()
            })
          }
        })
      },
      // 删除服务
      removeService(groupId, service) {
        this.$Modal.confirm({
          title: '系统提示',
          content: '确定删除' + service.id + '服务',
          loading: true,
          onOk: () => {
            Fetch.delete({
              url: '/api/environments/' + this.$route.params.environmentId + '/groups/' + groupId + '/services/' + service.id,
              done: () => {
                this.$Modal.remove()
              }
            }).then((res) => {
              this.$Message.success({
                content: '删除' + service.id + '服务成功！',
                duration: this.DURATION
              })
              this.init()
            })
          }
        })
      },
      // 添加服务完成
      addModifyServiceFinish() {
        this.init()
      },
      // 添加修改服务， 有service则为修改
      addModifyService(groupId, service, isClone) {
        if (!groupId) {
          this.serviceParams = {
            groupId: '',
            clone: false,
            serviceGroupList: this.serviceGroupList
          }
        } else {
          if (!service) {
            this.serviceParams = {
              groupId,
              clone: false
            }
          } else {
            let t = {
              groupId,
              clone: !!isClone
            }
            if (isClone) {
              t.service = Object.assign({}, service, {id: service.id + '-copy'})
            } else {
              t.service = Object.assign({}, service)
            }
            this.serviceParams = t
          }
        }
        this.serviceAddVisible = true
      },
      // 服务详情
      serviceDetail(group, service) {
        localStorage.setItem('groupName', group.name)
        this.$router.push('/home/environment/' + this.environmentId + '/info/' + group.id + '/' + service.id)
      },
      // 初始化页面
      init() {
        let vm = this
        Fetch.get({
          url: '/api/environment/info',
          params: {environmentId: vm.environmentId},
          done: () => {
            vm.isLoading = false
          }
        }).then((res) => {
          vm.environment = res.data
          localStorage.setItem('secondaryDomain', vm.environment.secondaryDomain)
          if (res.data && res.data.groups) {
            vm.serviceGroupList = res.data.groups
            // 在添加服务弹窗中新增服务组后，会返回一个服务组对象, 用于在新增服务弹窗中自动填写服务组名称
            if (vm.serviceGroupAddObj.id) {
              vm.serviceParams = {
                groupId: '',
                clone: false,
                serviceGroupList: vm.serviceGroupList,
                serviceGroupAddObj: Object.assign({}, vm.serviceGroupAddObj)
              }
              vm.serviceGroupAddObj = {}
            } else {
              vm.serviceParams = {
                groupId: '',
                clone: false,
                serviceGroupList: vm.serviceGroupList
              }
            }
            vm.$nextTick(function () {
              vm.getEnvEvents()
              vm.getAccessRight()
            })
          }
          if (res.environmentInfo && res.environmentInfo.code === '0') {
            vm.environmentInfo = res.environmentInfo.data
          } else {
            vm.$Message.warning(res.environmentInfo.message)
          }
        })
      },
      // 获取访问权
      getAccessRight() {
        Fetch.get({
          url: '/api/environments/' + this.environmentId + '/ingresses'
        }).then((res) => {
          // 将二级数组所有访问权拼装、合并成一个数组
          let accessTemp = []
          for (let i = 0; i < res.data.length; i++) {
            const access = res.data[i]
            for (let j = 0; j < access.paths.length; j++) {
              const path = access.paths[j]
              accessTemp.push(Object.assign({serviceId: path.serviceId, link: 'http://' + access.host + path.path}, access))
            }
          }
          // 将访问权映射到服务上
          for (let i = 0; i < this.serviceGroupList.length; i++) {
            const group = this.serviceGroupList[i]
            for (let k = 0; k < group.serviceList.length; k++) {
              const service = group.serviceList[k]
              for (let j = 0; j < accessTemp.length; j++) {
                const access = accessTemp[j]
                if (access.serviceId === service.id || access.serviceId === service.id + '-management') {
                  this.$set(service, 'access', access)
                  // rabbitmq， eureka， uimp-core-msdashboard能够直接访问
                  if (['rabbitmq', 'eureka', 'uimp-core-msdashboard'].indexOf(service.id) !== -1) {
                    this.$set(service, 'canLink', true)
                  }
                }
              }
            }
          }
        })
      },
      // 获取环境事件
      getEnvEvents() {
        Fetch.get({
          url: '/api/environments/' + this.environmentId + '/events'
        }).then((res) => {
          // 错误信息只获取错误信息进行处理
          let errors = res.data.filter((e) => {
            return e.type === 'Warning'
          })
          for (let i = 0; i < this.serviceGroupList.length; i++) {
            const group = this.serviceGroupList[i]
            for (let k = 0; k < group.serviceList.length; k++) {
              const service = group.serviceList[k]
              for (let j = 0; j < errors.length; j++) {
                const e = errors[j]
                // 处于活动的服务，不展示错误事件
                if (e.service === service.id && service.status !== 'active') {
                  this.$set(service, 'error', e.message)
                }
              }
            }
          }
        })
      },
      // 删除服务组
      serviceGroupDelete(group) {
        this.$Modal.confirm({
          title: '系统提示',
          content: '确定删除' + group.name + '服务组？',
          loading: true,
          onOk: () => {
            Fetch.delete({
              url: '/api/environments/' + this.environmentId + '/groups/' + group.id
            }).then((res) => {
              this.$Message.success({
                content: '删除' + group.name + '服务组成功！',
                duration: this.DURATION
              })
              this.init()
              this.$Modal.remove()
            })
          }
        })
      },
      // 添加服务组完成
      serviceGroupAddFinish(ret) {
        this.serviceGroupAddObj = ret
        this.init()
      },
      // 添加，编辑服务组
      serviceGroupMani(group) {
        if (group) {
          this.serviceGroupForm = {
            environmentId: this.environmentId,
            groupId: group.id,
            name: group.name,
            description: group.description ? group.description : ''
          }
        } else {
          this.serviceGroupForm = {
            environmentId: this.environmentId,
            groupId: '',
            name: '',
            description: ''
          }
        }
        this.groupVisible = true
      },
      // search可以是服务也可以是服务组
      searchService(search) {
        let temp = []
        this.environment.groups.forEach((group) => {
          let name = group.name ? group.name : group.environmentId
          if (name.indexOf(search) !== -1) {
            temp.push(group)
          } else if (group.serviceList && group.serviceList.length > 0) {
            for (let i = 0; i < group.serviceList.length; i++) {
              const s = group.serviceList[i]
              if (s.id.indexOf(search) !== -1) {
                temp.push(group)
                break
              }
            }
          }
        })
        this.serviceGroupList = temp
      }
    },
    watch: {
      $route(val) {
        let vm = this
        vm.$nextTick(function () {
          vm.environmentId = val.params.environmentId
          vm.domain = localStorage.getItem('domain')
          vm.init()
        })
      }
    }
  }
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.environment-info {
  position: relative;
  min-height: 160px;
}
.environment-info-box {
  line-height: 32px;
  background-color: #fff;
  padding: 15px;
  border-radius: 4px;
  border: 1px solid #eee;
}
.modal-add {
  position: relative;
  padding: 10px 20px 10px 0;
}
.button-add {
  .iconfont:hover {
    color: #fff;
  }
  + .button-add {
    margin-left: 10px;
  }
}
.service-group-table {
  margin-top: 20px;
  margin-bottom: 50px;
}
.group-card {
  margin-top: 20px;
  margin-bottom: 50px;
  padding: 10px 0 30px 0;
  .no-data {
    text-align: center;
    padding: 10px 30px 0 30px;
    color: #999;
  }
}
.group-box {
  border: 1px solid #eee;
  margin-bottom: 8px;
  .group-head {
    background-color: #f5f5f5;
    line-height: 40px;
    padding: 0 10px;
    border-bottom: 1px solid #eee;
    .zl-link {
      display: inline-block;
      font-weight: bold;
    }
    .group-mani {
      margin-left: 5px;
      vertical-align: middle;
      color: #4d98cf;
      text-align: center;
      .group-more {
        font-size: 22px;
        vertical-align: -4px;
      }
    }
  }
  .flex-mani {
    padding-left: 20px;
    width: 160px;
    text-align: right;
    .service-mani {
      margin-left: 5px;
      vertical-align: middle;
      text-align: center;
      color: #4d98cf;
      .service-more {
        font-size: 22px;
        vertical-align: -4px;
      }
    }
  }
}
.service-box {
  line-height: 40px;
  padding-right: 10px;
  font-size: 14px;
  .flex-status {
    width: 40px;
    text-align: center;
  }
  .flex-node {
    position: relative;
    padding: 0 8px;
    > span {
      vertical-align: middle;
      margin-right: 5px;
    }
    .icon-mani {
      color: #fff;
      background-color: #4d98cf;
      cursor: pointer;
      margin-right: 5px;
      vertical-align: middle;
      &:hover {
        color: #fff;
        background-color: #1392ec;
      }
    }
    .pod-mani {
      display: none;
      position: absolute;
      left: 0;
      right: 0;
      top: -23px;
      height: 30px;
      background-color: #fff;
      line-height: 30px;
      text-align: center;
      border: 1px solid #eee;
      .flex-1 {
        cursor: pointer;
        color: #4d98cf;
         + .flex-1 {
          border-left: 1px solid #eee;
        }
        &:hover {
          background-color: rgba(77, 153, 207, 0.1);
        }
      }
    }
    &:hover {
      .pod-mani {
        display: flex;
      }
    }
  }
  .flex-name {
    width: 15%;
    .service-name {
      display: inline-block;
      max-width: 85%;
      padding-right: 4px;
      margin-top: -2px;
      word-wrap:normal;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      padding-right: 10px;
      vertical-align: middle;
    }
    .service-tip {
      display: inline-block;
      vertical-align: 1px;
      width: 20px;
      color: #e45049;
      font-size: 14px;
    }
  }
  .flex-link {
    padding-left: 6px;
  }
}
.image-update-modal {
  padding: 30px 50px 30px 20px;
}
.service-box /deep/ {
  .ivu-tooltip {
    width: 100%;
    vertical-align: top;
    word-wrap:normal;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .ivu-dropdown-menu {
    min-width: 80px;
  }
}
.service-tip /deep/ {
  .ivu-tooltip-content .ivu-tooltip-inner {
    white-space: normal;
  }
}
</style>
